package cn.bone.alibabacloud.controller;

import cn.bone.alibabacloud.base.handler.CustomerBlockHandler;
import cn.bone.springcloud.base.bean.CommonResult;
import cn.bone.springcloud.base.bean.Ref;
import cn.bone.springcloud.bean.Payment;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.UUID;

@RestController
public class RateLimitController {

    @RequestMapping(value = "/byResource",produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @SentinelResource(value = "byResource", blockHandler = "handleException")
    public CommonResult byResource(){
        Payment payment = new Payment();
        payment.setId(1L);
        payment.setSerial(UUID.randomUUID().toString());
        return Ref.okMessage(payment,"按资源名称限流测试ok");
    }

    public CommonResult handleException(BlockException e){
        return Ref.error(e.getClass().getCanonicalName()+"\t服务不可用");
    }

    @RequestMapping(value = "/rateLimit/byUrl",produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @SentinelResource(value = "byUrl")
    public CommonResult byUrl(){
        Payment payment = new Payment();
        payment.setId(1L);
        payment.setSerial(UUID.randomUUID().toString());
        return Ref.okMessage(payment,"按资源名称限流测试ok");
    }

    /*
    自定义了降级方法，在sentinel-dashboard中
        如果是按URL地址作为资源名字来设置规则，降级之后走的是默认返回值
        按@SentinelResource中指定的资源名字来设置规则，降级之后走的就是自定义的返回值
            如果使用了自定义类，方法必须是static的静态方法
            方法的参数必须要有BlockException e
    */
    @RequestMapping(value = "/rateLimit/customerBlockHandler",produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @SentinelResource(value = "customerBlockHandler",
            blockHandlerClass = CustomerBlockHandler.class,
            blockHandler = "handlerException2"
    )
    public CommonResult customerBlockHandler(){
        Payment payment = new Payment();
        payment.setId(1L);
        payment.setSerial(UUID.randomUUID().toString());
        return Ref.okMessage(payment,"自定义返回值");
    }
}
